import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileSystemView;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class GUI {
    public  static void main(String[] args) {
        MainDialog mainDialog = new MainDialog();
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            SwingUtilities.updateComponentTreeUI(mainDialog.pathOptionPanel);
            mainDialog.pack();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

class MainDialog extends JFrame {
    String LogPath;

    // Main Panel
    JPanel main;

    // Path Option Panel Components
    JLabel log_path_label;
    JTextField log_path;
    JButton pathSelector;

    JPanel pathOptionPanel_back;
    JPanel pathOptionPanel;

    // Start Panel
    JPanel start_panel;
    JButton start;

    // Work State Panel Components
    static JTextArea workState;

    JPanel workStatePanel_back;
    JScrollPane workStatePanel;

    // Data Table Panel

    JPanel dataPanel;

    public MainDialog() {
        this.setLayout(new BorderLayout());

        ////////////////////////////////////////////////////Left_Panel//////////////////////////////////////////////
        main = new JPanel();
        main.setLayout(new BorderLayout());

        /********************path option panel***********************/
        pathOptionPanel_back = new JPanel();
        pathOptionPanel_back.setBackground(Color.WHITE);
        pathOptionPanel_back.setBorder(BorderFactory.createTitledBorder("Path Option"));

        pathOptionPanel = new JPanel();
        pathOptionPanel.setLayout(new GridLayout(2, 1, 0, 0));
        pathOptionPanel.setBackground(Color.WHITE);
        pathOptionPanel.setBorder(new EmptyBorder(0, 4, 0, 4));
        pathOptionPanel.setPreferredSize(new Dimension(400, 100));

        int label_length = 34;

        log_path_label = new JLabel("LOG Input Path:");
        JPanel tmpPanel = new JPanel();
        tmpPanel.setBackground(Color.WHITE);
        log_path = new JTextField(label_length);
        //rcg_path.setSize(140, 60);
        pathSelector = new JButton("File");
        pathSelector.addActionListener(new ChooseLogPathListener());

        tmpPanel.add(log_path);
        tmpPanel.add(pathSelector);

        pathOptionPanel.add(log_path_label);
        pathOptionPanel.add(tmpPanel);

        pathOptionPanel_back.add(pathOptionPanel);
        main.add(pathOptionPanel_back, BorderLayout.NORTH);
        //**********************Start Button*************************//
        start_panel = new JPanel();
        start_panel.setLayout(new GridLayout(1, 1));
        start_panel.setBackground(Color.WHITE);
        start_panel.setPreferredSize(new Dimension(400, 100));
        start = new JButton("Start!");
        start.addActionListener(new StartListener());
        start_panel.add(start, CENTER_ALIGNMENT);
        main.add(start_panel, BorderLayout.CENTER);
        /////////////////////////////////////////// Work State Panel;
        workStatePanel_back = new JPanel();
        workStatePanel_back.setBackground(Color.WHITE);
        workStatePanel_back.setPreferredSize(new Dimension(400,200));
        workStatePanel_back.setBorder(BorderFactory.createTitledBorder("Work State"));


        workState = new JTextArea(10, 34);
        workState.setAutoscrolls(true);
        workState.setBorder(BorderFactory.createLineBorder(Color.lightGray));
        workState.setLineWrap(true);
        workState.setForeground(Color.black);
        workState.setEditable(false);

        workStatePanel = new JScrollPane(workState);
        workStatePanel.setBackground(Color.WHITE);
        workStatePanel.setBorder(new EmptyBorder(4, 4, 4, 4));

//        workStatePanel.add(workState);
        workStatePanel_back.add(workStatePanel);
        main.add(workStatePanel_back, BorderLayout.SOUTH);

        this.add(main,BorderLayout.CENTER);


        this.setSize(400, 400);
        this.setLocation(200, 200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

    }

    class ChooseLogPathListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            JFileChooser chooser = new JFileChooser();
            FileSystemView fileSystemView = FileSystemView.getFileSystemView();
            chooser.setCurrentDirectory(fileSystemView.getHomeDirectory());
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            if (chooser.showOpenDialog(MainDialog.this) == JFileChooser.APPROVE_OPTION) {
                String logPath = chooser.getSelectedFile().getAbsolutePath();
                log_path.setText(logPath);
            }
        }
    }

    class StartListener implements ActionListener {
        private ArrayList<String> rcgFilesPaths;
        private ArrayList<String> rclFilesPaths;
//        private ThreadPoolExecutor threadPoolExecutor;
        private String rcgAddress;
        private String rclAddress;
        @Override
        public void actionPerformed(ActionEvent e) {
            SwingWorker worker = new SwingWorker() {
                @Override
                protected Object doInBackground() throws Exception {
                    start.setEnabled(false);
                    if (log_path.getText().isEmpty() || log_path.getText() == null) {
                        errorWorkState("Log Path is not available;");
                        start.setEnabled(true);
                        return null;
                    }
                    getAllRcgRclFiles(log_path.getText());

                    infoWorkState("Total Task: " + rcgFilesPaths.size() + ";");

//            threadPoolExecutor = new ThreadPoolExecutor(
//                    4,
//                    8,
//                    500,
//                    TimeUnit.MILLISECONDS,
//                    new LinkedBlockingQueue<>(),
//                    Executors.defaultThreadFactory(),
//                    new ThreadPoolExecutor.AbortPolicy());

                    infoWorkState("ThreadPool Excuted;");
                    String fileName;
                    for (int i = 0; i < rcgFilesPaths.size(); i++) {
                        rcgAddress = rcgFilesPaths.get(i);
                        if (System.getProperty("os.name").startsWith("Windows")) {
                            fileName = rcgAddress.substring(rcgAddress.lastIndexOf("\\") + 1,
                                    rcgAddress.lastIndexOf("."));
                        } else {
                            fileName = rcgAddress.substring(rcgAddress.lastIndexOf("/") + 1,
                                    rcgAddress.lastIndexOf("."));
                        }
                        if (isMatchable(fileName)) {
                            if (rcgAddress == null || rcgAddress.isEmpty() || rclAddress == null || rclAddress.isEmpty()) {
                                warningWorkState("File " + rcgAddress + " cannot match to a rcg file;");
                                continue;
                            }
                            infoWorkState("Create task: " + fileName + ";");
                            Analyzer analyzer = new Analyzer(rcgAddress, rclAddress, fileName);
                            analyzer.run();
//                    threadPoolExecutor.execute(analyzer);
//                    infoWorkState("线程池中线程数目："+threadPoolExecutor.getPoolSize()+"，队列中等待执行的任务数目："+
//                            threadPoolExecutor.getQueue().size()+"，已执行玩别的任务数目："+threadPoolExecutor.getCompletedTaskCount());
                        }
                    }
//            threadPoolExecutor.shutdown();

                    start.setEnabled(true);
                    return null;
                }
            };
            worker.execute();
            return;
        }

        private boolean isMatchable(String rcgFileName) {
            for (int i = 0; i < rclFilesPaths.size(); i++) {
                if (rclFilesPaths.get(i).contains(rcgFileName)) {
                    rclAddress = rclFilesPaths.get(i);
                    return true;
                }
            }
            return false;
        }

        private void getAllRcgRclFiles(String rootPath) {
            rcgFilesPaths = new ArrayList<>();
            rclFilesPaths = new ArrayList<>();
            File file = new File(rootPath);
            File[] files = file.listFiles(new RcgRclFileFliter());
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory()) {
                    continue;
                } else {
                    infoWorkState("Scanned file " + files[i].getPath());
                    if (files[i].getName().endsWith(".rcg")) {
                        rcgFilesPaths.add(files[i].getPath());
                    } else {
                        rclFilesPaths.add(files[i].getPath());
                    }
                }
            }
        }
    }

    public static void infoWorkState(String info) {
        workState.append("INFO: " + info + "\n");
        workState.setCaretPosition(workState.getText().length());
    }

    public static void warningWorkState(String warning) {
        workState.append("WARNING: " + warning + "\n");
        workState.setCaretPosition(workState.getText().length());
    }

    public static void errorWorkState(String error) {
        workState.append("ERROR: " + error + "\n");
        workState.setCaretPosition(workState.getText().length());
    }

}
